package com.chukun.multi.guarded.example;

import com.chukun.multi.guarded.Blocker;
import com.chukun.multi.guarded.ConditionVarBlocker;
import com.chukun.multi.guarded.GuardedAction;
import com.chukun.multi.guarded.Predicate;
import com.chukun.multi.utils.Debug;
import com.chukun.multi.utils.Tools;
import java.util.Timer;
import java.util.TimerTask;

/**
 * 负责连接告警服务器，并发送告警信息至告警服务器
 *
 */
public class AlarmAgent {
    // 用于记录AlarmAgent是否连接上告警服务器
    private volatile  boolean connectionToServer=false;
    // 模式角色：GuardedSuspension.Predicate
    private final  Predicate agentConnected = ()->connectionToServer;

    // 模式角色：GuardedSuspension.Blocker
    private final Blocker blocker = new ConditionVarBlocker();

    //心跳检测
    private final Timer heartbeatTimer = new Timer(true);

    public  void sendAlarm(final  AlarmInfo alarmInfo) throws Exception {
        /*
         * 可能需要等待，直到AlarmAgent连接上告警服务器（或者连接中断后重新连连上服务器）。<br/>
         */
        // 模式角色：GuardedSuspension.GuardedAction
        GuardedAction<Void> guardedAction = new GuardedAction<Void>(agentConnected) {
            @Override
            public Void call() throws Exception {
                doSendAlarm(alarmInfo);
                return null;
            }
        };
        blocker.callWithGuard(guardedAction);
    }

    // 通过网络连接将告警信息发送给告警服务器
    private  void doSendAlarm(AlarmInfo alarmInfo){
        // 省略其他代码
        Debug.info("sending alarm " + alarmInfo);

        // 模拟发送告警至服务器的耗时
        try {
            Thread.sleep(50);
        } catch (Exception e) {

        }
    }

    public void init(){
        //报警连接线程
        Thread connectingThread = new Thread(new ConnectingTask());
        connectingThread.start();
        heartbeatTimer.schedule(new HeartbeatTask(),60000,2000);
    }

    public void disconnect() {
        // 省略其他代码
        Debug.info("disconnected from alarm server.");
        connectionToServer = false;
    }

    protected void onConnected(){
        try{
            blocker.signalAfter(()->{
                connectionToServer=true;
                Debug.info("connected.....");
                return Boolean.TRUE;
            });
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    protected  void onDisconnected(){
        connectionToServer=false;
    }

    // 负责与告警服务器建立网络连接
    private class ConnectingTask implements Runnable {
        @Override
        public void run() {
            // 省略其他代码

            // 模拟连接操作耗时
            Tools.randomPause(100, 40);

            onConnected();
        }
    }

    /**
     * 心跳定时任务：定时检查与告警服务器的连接是否正常，发现连接异常后自动重新连接
     */
    private class HeartbeatTask extends TimerTask {
        // 省略其他代码

        @Override
        public void run() {
            // 省略其他代码

            if (!testConnection()) {
                onDisconnected();
                reconnect();
            }

        }

        private boolean testConnection() {
            // 省略其他代码

            return true;
        }

        private void reconnect() {
            ConnectingTask connectingThread = new ConnectingTask();

            // 直接在心跳定时器线程中执行
            connectingThread.run();
        }

    }



}
